package br.com.lopes.gci.manager;

import static br.com.lopes.gci.util.Constants.FINALIZANDO_METODO;
import static br.com.lopes.gci.util.Constants.INICIANDO_METODO;
import static br.com.lopes.gci.util.Constants.PERFIL_CORRETOR;
import static br.com.lopes.gci.util.Constants.PERFIL_GERENTE;

import java.util.List;

import org.apache.log4j.Logger;
import org.hibernate.FetchMode;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.MatchMode;
import org.hibernate.criterion.Restrictions;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import br.com.lopes.gci.dao.IClienteHibernateDAO;
import br.com.lopes.gci.dao.IEnderecoHibernateDAO;
import br.com.lopes.gci.exception.DAOException;
import br.com.lopes.gci.exception.ManagerException;
import br.com.lopes.gci.model.Cliente;

@Service
public class ClienteManager {
	
	private static final Logger LOGGER = Logger.getLogger(ClienteManager.class);	
	
	@Autowired
	private IClienteHibernateDAO clienteHibernateDAO ;
	@Autowired
	private IEnderecoHibernateDAO enderecoHibernateDAO ;
	
	public List<Cliente> pesquisarCliente(Cliente cliente) throws ManagerException{
		LOGGER.debug(INICIANDO_METODO + "pesquisarCliente(Cliente)");
		System.out.println(INICIANDO_METODO + "pesquisarCliente(Cliente)");
		try{
			
			DetachedCriteria criteria = DetachedCriteria.forClass(Cliente.class);
			if(cliente.getStatus().getCodigo()!=null && cliente.getStatus().getCodigo()>0){
				criteria.setFetchMode("status", FetchMode.JOIN);
				criteria.createAlias("status", "st");
				criteria.add(Restrictions.eq("st.codigo", cliente.getStatus().getCodigo()));
			}
			if(cliente.getNomeRazaoSocial()!=null && !cliente.getNomeRazaoSocial().equals("")){
				criteria.add(Restrictions.or(
							Restrictions.like("nome",cliente.getNomeRazaoSocial() ,MatchMode.ANYWHERE), 
							Restrictions.like("razaoSocial",cliente.getNomeRazaoSocial() ,MatchMode.ANYWHERE)));
			}
			
			if(cliente.getTelefoneComercial()!=null && !cliente.getTelefoneComercial().equals("")){
				criteria.add(Restrictions.like("telefoneComercial", cliente.getTelefoneComercial(),MatchMode.ANYWHERE));
			}
			if(cliente.getCpfCnpj()!=null && !cliente.getCpfCnpj().equals("")){
				criteria.add(Restrictions.or(
						Restrictions.like("cpf", cliente.getCpfCnpj(),MatchMode.ANYWHERE), 
						Restrictions.like("cnpj", cliente.getCpfCnpj(),MatchMode.ANYWHERE))); 
				
			}
			if(cliente.getEmail()!=null && !cliente.getEmail().equals("")){
				criteria.add(Restrictions.like("email", cliente.getEmail(),MatchMode.ANYWHERE));
			}
			if (PERFIL_CORRETOR.equals(cliente.getFuncionario().getPerfil().getCodigo())){
				criteria.setFetchMode("funcionario", FetchMode.JOIN);
				criteria.createAlias("funcionario", "cor");
			
			} else if (PERFIL_GERENTE.equals(cliente.getFuncionario().getPerfil().getCodigo())){
				criteria.setFetchMode("funcionario", FetchMode.JOIN);
				criteria.createAlias("funcionario", "cor");
				criteria.setFetchMode("cor.gerente", FetchMode.JOIN);
				criteria.createAlias("cor.gerente", "ger");
				
			}
			return clienteHibernateDAO.findByCriteria(criteria);
			
		} catch (DAOException e) {
			throw new ManagerException(e);
		
		}finally{
			LOGGER.debug(FINALIZANDO_METODO + "pesquisarCliente(Cliente)");
		}
	}
	
	
	@Transactional(rollbackFor={DAOException.class})
	public void incluirCliente(Cliente cliente) throws ManagerException{
		System.out.println(INICIANDO_METODO + "incluirCliente(ClienteVO)");
		LOGGER.debug(INICIANDO_METODO + "incluirCliente(ClienteVO)");
		try{
			
			enderecoHibernateDAO.insert(cliente.getEndereco());
			clienteHibernateDAO.insert(cliente);
		}catch(DAOException e){
			LOGGER.error(e.getMessage());
			throw new ManagerException(e);
		}finally{
			LOGGER.debug(FINALIZANDO_METODO + "incluirCliente(ClienteVO)");
		}
		
		
	}

	
	public void alterarCliente(Cliente cliente) throws ManagerException{
		LOGGER.debug(INICIANDO_METODO + "alterarCliente(ClienteVO)");
		System.out.println(INICIANDO_METODO + "alterarCliente(ClienteVO)");
		try{
			clienteHibernateDAO.update(cliente); 
			
		}catch(DAOException e){
			LOGGER.error(e.getMessage());
			throw new ManagerException(e);
		}finally{
			LOGGER.debug(FINALIZANDO_METODO + "alterarCliente(ClienteVO)");
			System.out.println(FINALIZANDO_METODO + "alterarCliente(ClienteVO)");
		}
		
		
	}
	@Transactional(rollbackFor={DAOException.class})
	public void excluirCliente(Cliente cliente) throws ManagerException{
		System.out.println(INICIANDO_METODO + "excluirCliente(Cliente)1");
		LOGGER.debug(INICIANDO_METODO + "excluirCliente(Cliente)");
		try{
			clienteHibernateDAO.delete(cliente);
			 
		}catch(DAOException e){
			LOGGER.error(e.getMessage());
			
			throw new ManagerException(e);
		}finally{
			LOGGER.debug(FINALIZANDO_METODO + "excluirCliente(ClienteVO)");
		}
		
		
	}
	
	public Cliente getClienteById(Cliente cliente) throws ManagerException {
		LOGGER.debug(INICIANDO_METODO + "getClienteById(Id)");
		try {
			DetachedCriteria criteria = DetachedCriteria.forClass(Cliente.class);
			criteria.add(Restrictions.eq("fac", cliente.getFac()));
			List<Cliente> clientes = clienteHibernateDAO.findByCriteria(criteria);
			if(!clientes.isEmpty()){
				return clientes.get(0);
			}else{
				return null;
			}
		} catch (DAOException e) {
			throw new ManagerException(e);
		} finally {
			LOGGER.debug(FINALIZANDO_METODO + "getClienteById(Id)");
		}
	}
	
}
